<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>vue响应式的原理</title>
</head>

<body>
  <h1>vue2的数据响应式原理 Object.defineProperties()</h1>
  <div>
    数量:
    <span id="span">1</span>
    <button id="btn">+</button>
  </div>
  <script>
    var data = { count: 1 }
    // Vue2 将会监听data中的属性, 一旦data中的count变化, 则修改DOM
    Object.defineProperties(data, {
      _count: { value: 1, writable: true },  // 保存具体的值
      count: {
        // 当访问: data.count 的值时, 就会自动调用该get方法获取结果
        get() {
          return this._count
        },
        // 当修改count属性时, 例如: data.count=1  data.count++
        // 将会自动调用set方法,并传入目标值 value
        set(value) {
          this._count = value
          // 此处可以顺便更新页面中使用count变量的哪些DOM元素
          span.innerHTML = value
        }
      }
    })
    btn.onclick = function () {
      data.count++
    }
  </script>



  <h1>vue3的数据响应式原理 new Proxy()</h1>
  <div>
    商品的数量:
    <span id="spanv3">1</span>
    <button id="btnv3">+</button>
  </div>
  <script>
    // 模拟vue3环境下的响应式变量
    var v3data = { count: 1 }
    // 使用new Proxy() 创建v3data的代理对象
    let v3dataProxy = new Proxy(v3data, {
      // 当修改代理对象的属性时, 将自动执行该set方法
      // v3dataProxy.count = 10
      set(obj, key, value) {   // obj目标对象 key目标属性 value目标值
        obj[key] = value
        // 更新UI DOM
        spanv3.innerHTML = value
      },
      // 当访问代理对象的属性时, 将自动执行该get方法 
      // v3dataProxy.count
      get(obj, key) {  // obj为目标对象, key就是属性名
        return obj[key]
      }
    })
    btnv3.onclick = function () {
      // 修改代理对象的count属性 将会更新UI
      v3dataProxy.count++
    }

  </script>

</body>

</html>